package com.jinzhi.jzweb.controller.resourceLibrary;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.jinzhi.api.exception.IFastApiException;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.ApiResult;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.ShiroUtils;
import com.jinzhi.jzweb.domain.vo.resourceLibrary.ImportStuClassBody;
import com.jinzhi.jzweb.domain.vo.resourceLibrary.eventresourceVO.*;
import com.jinzhi.jzweb.service.resourceLibrary.EventResourceClassService;
import com.jinzhi.jzweb.service.resourceLibrary.EventResourceStatisticService;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @ClassName EventResourceClassController 金职资源库前台班级管理接口
 * @Description:
 * @Author: ak
 * @CreateDate: 2024/5/11 9:43
 * @UpdateUser:
 * @UpdateDate: 2024/5/11 9:43
 * @UpdateRemark:
 * @Version: 1.0
 */

@Controller
@RequestMapping("/jzweb/eclassresource")
@Api(value = "班级管理", tags = {"班级管理"})
@CrossOrigin
public class eResourceClassController extends BaseController {

    @Autowired
    private EventResourceClassService classService;
    @Autowired
    private EventResourceStatisticService statisticService;
    @Autowired
    private UserService userService;

    // 查询班级
    @ApiOperation("查询班级")
    @GetMapping("/list")
    @ResponseBody
    public Result list(String classname, String name, String mobile, Integer pageNum, Integer pageSize) {
        return Result.ok(classService.list(classname, name, mobile, pageNum, pageSize));
    }

    // 班级详情
    @ApiOperation("班级详情")
    @GetMapping("/getClassDetail")
    @ResponseBody
    public Result classDetail(String classId, Integer pageNum, Integer pageSize) {
        return Result.ok(classService.getClassDetails(Long.parseLong(classId), pageNum, pageSize));
    }

    // 学生学习详情
    @ApiOperation("学生学习详情")
    @GetMapping("/getLearnDetail")
    @ResponseBody
    public Result learnDetail(String userId, Integer type, @RequestParam("current") Integer pageNum, @RequestParam("size") Integer pageSize) {
        return Result.ok(statisticService.learnDetails(Long.parseLong(userId), type, pageNum, pageSize));
    }

    // 学生练题信息详情
    @ApiOperation("学生练题信息详情")
    @GetMapping("/getPracticeDetail")
    @ResponseBody
    public Result practiceDetail(String userId, Integer pageNum, Integer pageSize) {
        return Result.ok(statisticService.practiceRecordDetails(Long.parseLong(userId), pageNum, pageSize));
    }

    /**
     * @auther: ak
     * @Description 查看学生练习试卷
     * @param:
     * @return:
     * @date: 2024/4/30 8:49
     */
    @ApiOperation("查看学生练习试卷")
    @GetMapping("/getExamPaper")
    @ResponseBody
    public ApiResult getExamPaper(Long practiceRecordId) {
        return ApiResult.success(statisticService.getExamPaper(practiceRecordId));
    }

    // 添加班级
    @ApiOperation("添加班级")
    @PostMapping("/inertClass")
    @ResponseBody
    public Result inertClass(@RequestBody AddClassVO addClassVO) {
        Result result = classService.batchSaveClass(addClassVO.getClassname(),
                addClassVO.getCreatername(), addClassVO.getStudentVOList());
        return result;
    }

    // 获取班级列表
    @ApiOperation("获取班级列表")
    @GetMapping("/classList")
    @ResponseBody
    public ApiResult classList() {
        return ApiResult.success(classService.classList());
    }

    // 修改班级信息
    @ApiOperation("修改班级信息")
    @GetMapping("/updateClass")
    @ResponseBody
    public ApiResult updateClass(@RequestParam("classId") String classId, @RequestParam("classname") String classname) {
        UserDO sysUser = ShiroUtils.getSysUser();
        return ApiResult.success(classService.updateClass(Long.parseLong(classId), classname, sysUser.getId()));
    }

    // 修改学生信息
    @ApiOperation("修改学生信息")
    @PostMapping("/updateStu")
    @ResponseBody
    public ApiResult updateStu(@RequestBody StudentVO studentVO) {
        boolean b = classService.updateStu(studentVO.getName(), studentVO.getMobile(),
                Long.valueOf(studentVO.getSex()), studentVO.getId(), null);
        return ApiResult.success(b);
    }

    // 重置密码
    @ApiOperation("重置密码")
    @PostMapping("/resetPwd")
    @ResponseBody
    public ApiResult resetPwd(@RequestBody ResetVO resetVO) {
        boolean b = classService.updateStu(null, null,
                null, resetVO.getId(), resetVO.getPassword());
        return ApiResult.success(b);
    }

    // 删除学生
    @ApiOperation("删除学生")
    @GetMapping("/quitClass")
    @ResponseBody
    public ApiResult quitStu(@RequestParam("userId") Long userId, @RequestParam("classId") Long classId) {
        return ApiResult.success(classService.quitStu(userId, classId));
    }

    // 删除班级
    @ApiOperation("删除班级")
    @GetMapping("/delete")
    @ResponseBody
    public ApiResult deleteClass(@RequestParam("classId") Long classId) {
        return ApiResult.success(classService.deleteClass(classId));
    }

    // 删除所有的练习和学习记录
    @ApiOperation("删除所有的练习和学习记录")
    @DeleteMapping("/deleteRecord")
    //@RequiresPermissions("classManage:exercises:remove")
    @ResponseBody
    public ApiResult deleteRecord() {
        return ApiResult.success(statisticService.deleteRecord());
    }

    @Log("导出全部班级信息")
    @ApiOperation("导出班级信息")
    @GetMapping("/exportClass")
    //@RequiresPermissions("jzweb:certificates:import")
    @ResponseBody
    public void exportClass(HttpServletResponse response,@RequestParam(value = "ids",required = false) List<Long> ids) {
        try {
            List<ClassesVO> list = ids.stream()
                    .map(id -> classService.getClassById(id))
                    .collect(Collectors.toList());

            //导出操作
            EasyPoiUtil.exportExcel(list, "班级信息", "班级信息",
                    ClassesVO.class, "班级信息表", response);
        } catch (Exception e) {
            throw new IFastApiException(ApiEnumError.NOTBATCHSTU.getCodeStr());
        }
    }

    @Log("导出班级详情信息")
    @ApiOperation("导出班级详情信息")
    @GetMapping("/exportClassDetail")
    //@RequiresPermissions("jzweb:certificates:import")
    @ResponseBody
    public void exportClassDetail(HttpServletResponse response, @RequestParam(value = "ids",required = false) List<Long> ids) {
        try {
            List<StudentDetailVO> list = ids.stream()
                    .map(id -> classService.getClassDetailById(id))
                    .collect(Collectors.toList());

            //导出操作
            EasyPoiUtil.exportExcel(list, "班级详情信息", "班级详情信息",
                    StudentDetailVO.class, "班级详情信息表", response);
        } catch (Exception e) {
            throw new IFastApiException(ApiEnumError.NOTBATCHSTU.getCodeStr());
        }
    }

    /**
     * @auther: ak
     * @Description 学生信息批量导入
     * @param:
     * @return:
     * @date: 2024/4/17 10:35
     */
    @ApiOperation("学生信息批量导入")
    @PostMapping("/import")
    @ResponseBody
    public ApiResult importExcel(MultipartFile file) throws Exception {

        // 判断文件格式
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return ApiResult.fail("文件格式错误，请选择.xls文件");
        }
        if (file == null) {
            return ApiResult.fail();
        }

        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(0);
        importParams.setHeadRows(1);

        List<ExcelStudentVO> excelStudentVOList = null;
        try {
            excelStudentVOList = ExcelImportUtil.importExcel(file.getInputStream(), ExcelStudentVO.class, importParams);
            file.getInputStream().close();
        } catch (NoSuchElementException e) {
            throw new RuntimeException("excel文件不能为空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        // excel校验手机号 导入失败则生成错误excel
        StringBuffer errList = new StringBuffer();
        ArrayList<String> errStringList = new ArrayList<>();
        ArrayList<String> mobilList = new ArrayList<>();


        for (ExcelStudentVO excelStudentVO : excelStudentVOList) {
            String mobile = excelStudentVO.getMobile();
            //手机号为空 格式不正确
            if (StrUtil.isEmpty(mobile) || !Pattern.matches("^1[3-9]\\d{9}$", mobile)) {
                errStringList.add(excelStudentVO.getName() + ": " + mobile + "手机号错误");
                continue;
            }
            // 正确但重复
            if (mobilList.contains(mobile)) {
                errStringList.add(excelStudentVO.getName() + ": " + mobile + "手机号重复");
            } else {
                mobilList.add(mobile);
            }
        }

        if (errStringList.size() != 0) {
            // 手机号有误 返回错误信息list
            //exportErrExcel(excelStudentVOList, errMobileList, duplicateMobilList, response);
            ApiResult<Object> fail = ApiResult.fail(EnumErrorCode.fail.getCode(), EnumErrorCode.fail.getMsg());
            if (errStringList.size() > 5) {
                fail.setData(JSONArray.parseArray(JSON.toJSONString(errStringList.subList(0, 4))));
            } else {
                fail.setData(JSONArray.parseArray(JSON.toJSONString(errStringList)));
            }
            return fail;
        }

        for (ExcelStudentVO excelStudentVO : excelStudentVOList) {
            if (excelStudentVO.getName() == null) {
                excelStudentVO.setName("");
            }
            if (excelStudentVO.getMobile() == null) {
                excelStudentVO.setMobile("");
            }
            if (excelStudentVO.getSex() == null) {
                excelStudentVO.setSex("");
            }
            String sex = excelStudentVO.getSex();
            if (sex.equals("男")) {
                excelStudentVO.setSex("1");
            } else if (sex.equals("女")) {
                excelStudentVO.setSex("2");
            } else if (sex.equals("未知")) {
                excelStudentVO.setSex("0");
            }
        }

        return ApiResult.success(excelStudentVOList);
    }

    /**
     *
     */
    @ApiOperation("班级批量添加学生")
    @PostMapping("/importStudent")
    @ResponseBody
    public Result importStudent(ImportStuClassBody importStuClassBody) throws Exception {
        MultipartFile file = importStuClassBody.getFile();

        // 判断文件格式
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return Result.fail("文件格式错误，请选择.xls文件");
        }
        if (file == null) {
            return Result.fail("上传文件不能为空");
        }

        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(0);
        importParams.setHeadRows(1);

        List<ExcelStudentVO> excelStudentVOList = null;
        try {
            excelStudentVOList = ExcelImportUtil.importExcel(file.getInputStream(), ExcelStudentVO.class, importParams);
            file.getInputStream().close();
        } catch (NoSuchElementException e) {
            throw new RuntimeException("excel文件不能为空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        // excel校验手机号 导入失败则生成错误信息
        StringBuffer errList = new StringBuffer();
        ArrayList<String> errStringList = new ArrayList<>();
        ArrayList<String> mobilList = new ArrayList<>();


        for (ExcelStudentVO excelStudentVO : excelStudentVOList) {
            String mobile = excelStudentVO.getMobile();
            //手机号为空 格式不正确
            if (StrUtil.isEmpty(mobile) || !Pattern.matches("^1[3-9]\\d{9}$", mobile)) {
                errStringList.add(excelStudentVO.getName() + ": " + mobile + "手机号错误");
                continue;
            }

            // 正确但重复
            if (mobilList.contains(mobile)) {
                errStringList.add(excelStudentVO.getName() + ": " + mobile + "手机号重复");
            }else if (userService.getMobile(mobile) != null) {
                return Result.fail("手机号：" + mobile + "已存在！");
            } else {
                mobilList.add(mobile);
            }
        }

        if (errStringList.size() != 0) {
            // 手机号有误 返回错误信息list
            //exportErrExcel(excelStudentVOList, errMobileList, duplicateMobilList, response);
            Result<Object> fail = Result.fail( "导入内容错误");
            if (errStringList.size() > 5) {
                fail.setData(JSONArray.parseArray(JSON.toJSONString(errStringList.subList(0, 4))));
            }else {
                fail.setData(JSONArray.parseArray(JSON.toJSONString(errStringList)));
            }
            return fail;
        }

        for (ExcelStudentVO excelStudentVO : excelStudentVOList) {
            if (excelStudentVO.getName() == null) {
                excelStudentVO.setName("");
            }
            if (excelStudentVO.getMobile() == null) {
                excelStudentVO.setMobile("");
            }
            if (excelStudentVO.getSex() == null) {
                excelStudentVO.setSex("");
            }
        }

        ArrayList<StudentVO> studentVOList = new ArrayList<>();
        for (ExcelStudentVO excelStudentVO : excelStudentVOList) {
            StudentVO studentVO = new StudentVO();
            BeanUtils.copyProperties(excelStudentVO, studentVO);

            String sex = excelStudentVO.getSex();
            if (sex.equals("男")) {
                studentVO.setSex(1);
            }else if (sex.equals("女")) {
                studentVO.setSex(2);
            }else if (sex.equals("未知")) {
                studentVO.setSex(0);
            }
            studentVOList.add(studentVO);
        }
        UserDO sysUser = ShiroUtils.getSysUser();
        ClassesVO classById = classService.getClassById(importStuClassBody.getClassId());
        // 添加班级学生
        return classService.batchSaveClass(classById.getName(), sysUser.getUsername(), studentVOList);
    }

    /**
     * @auther: ak
     * @Description 导入模板下载
     * @param:
     * @return:
     * @date: 2024/4/26 13:42
     */
    @ApiOperation("导入模板下载")
    @GetMapping("/export")
    public ApiResult exportExcel(HttpServletResponse response) throws IOException {
        String fileName = URLEncoder.encode("学生信息导入模板", "UTF-8");
        // 格式：姓名 用户名 性别
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("学生信息表");

        Row r = sheet.createRow(0);
        r.createCell(0).setCellValue("姓名");
        r.createCell(1).setCellValue("手机号");
        r.createCell(2).setCellValue("性别");

        ServletOutputStream ops = response.getOutputStream();

        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
        workbook.write(ops);
        ops.close();

        return ApiResult.success();
    }


    @GetMapping()
        //@RequiresPermissions("jzweb:eventresourceAllocation:add")
    String classdetail(String parentId, Model model) {
        model.addAttribute("parentId", parentId);
        if (parentId != null && !parentId.equals("")) {
            model.addAttribute("parentId", parentId);
            System.out.println("parentId:---Chapter" + parentId);
        }
        return "/jzweb/eclassresource/classdetail/classdetail";
    }

    @GetMapping("/classdetail/classdetail")
        //@RequiresPermissions("classManage:classdetail:classdetail")
    String classdetail() {
        return "/classManage/classdetail/classdetail";
    }

    @GetMapping("/classdetail/add")
//    @RequiresPermissions("classManage:classdetail:add")
    String add() {
        return "/classManage/classdetail/add";
    }

    @GetMapping("/classdetail/edit")
//    @RequiresPermissions("classManage:classdetail:edit")
    String edit() {
        return "/classManage/classdetail/edit";
    }

    @GetMapping("/classdetail/export")
//    @RequiresPermissions("classManage:classdetail:export")
    String export() {
        return "/classManage/classdetail/export";
    }

    @GetMapping("/classdetail/import")
//    @RequiresPermissions("classManage:classdetail:import")
    String importExcel() {
        return "/classManage/classdetail/import";
    }

    @GetMapping("/classdetail/repassword")
//    @RequiresPermissions("classManage:classdetail:repassword")
    String repassword() {
        return "/classManage/classdetail/repassword";
    }

    @GetMapping("/addclass/add")
//    @RequiresPermissions("classManage:addclass:add")
    String addClass() {
        return "/classManage/addclass/add";
    }

    @GetMapping("/addclass/addclass")
//    @RequiresPermissions("classManage:addclass:addclass")
    String addclass() {
        return "/classManage/addclass/addclass";
    }

    @GetMapping("/addclass/edit")
//    @RequiresPermissions("classManage:addclass:edit")
    String classEdit() {
        return "/classManage/addclass/edit";
    }

    @GetMapping("/exercises/add")
//    @RequiresPermissions("classManage:exercises:add")
    String exercisesAdd() {
        return "/classManage/exercises/add";
    }

    @GetMapping("/exercises/detail")
//    @RequiresPermissions("classManage:exercises:detail")
    String exercisesDetail() {
        return "/classManage/exercises/detail";
    }

    @GetMapping("/exercises/edit")
//    @RequiresPermissions("classManage:exercises:edit")
    String exercisesEdit() {
        return "/classManage/exercises/edit";
    }

    @GetMapping("/exercises/exercises")
//    @RequiresPermissions("classManage:exercises:exercises")
    String exercisesExercises() {
        return "/classManage/exercises/exercises";
    }

    @GetMapping("/manage/add")
//    @RequiresPermissions("classManage:manage:add")
    String manageAdd() {
        return "/classManage/manage/add";
    }

    @GetMapping("/manage/edit")
//    @RequiresPermissions("classManage:manage:edit")
    String manageEdit() {
        return "/classManage/manage/edit";
    }

    @GetMapping("/manage/detail")
//    @RequiresPermissions("classManage:manage:detail")
    String manageDetail() {
        return "/classManage/manage/detail";
    }

    @GetMapping("/manage/manage")
//    @RequiresPermissions("classManage:manage:manage")
    String manageManage() {
        return "/classManage/manage/manage";
    }

    @GetMapping("/studentInformation/add")
//    @RequiresPermissions("classManage:studentInformation:add")
    String studentInformationAdd() {
        return "/classManage/studentInformation/add";
    }

    @GetMapping("/studentInformation/edit")
//    @RequiresPermissions("classManage:studentInformation:edit")
    String studentInformationEdit() {
        return "/classManage/studentInformation/edit";
    }

    @GetMapping("/studentInformation/studentInformation")
//    @RequiresPermissions("classManage:studentInformation:studentInformation")
    String studentInformationStudentInformation() {
        return "/classManage/studentInformation/studentInformation";
    }
}
